package com.umeox.watch.moto.agora

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.*
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.umeox.watch.moto.dataservice.DataProvider
import io.agora.rtc.Constants.*
import io.agora.rtc.IRtcEngineEventHandler
import io.agora.rtc.RtcEngine
import io.agora.rtc.models.ChannelMediaOptions
import io.agora.rtc.video.VideoCanvas
import io.agora.rtc.video.VideoEncoderConfiguration
import io.agora.rtm.*
import java.util.*
import java.util.concurrent.ScheduledThreadPoolExecutor
import java.util.concurrent.ThreadFactory
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger


/**
 * Created by Rambo 2021/8/26
 * Describe:
 */
class AgoraService private constructor(context: Context) : RtmClientListener, ResultCallback<Void>,
    RtmChannelListener, RtmCallEventListener {

    companion object {

        const val CALL_TYPE_VIDEO = 1

        const val CALL_TYPE_VOICE = 2

        const val CALL_TYPE_PTT = 3

        private const val MSG_LOGOUT = 0 //退出登录消息

        private const val MSG_JOIN_TIMEOUT = 2 //加入频道超时消息

        private const val MSG_USER_OFFLINE = 3 //网络差造成掉线

        private const val MSG_INCOMING_CALL_NOT_RECEIVE_INVITE = 4 //一定时间内没有收到邀请

        private const val RESPONSE_BUSY = "{\"refuse\": 1000}"

        @SuppressLint("StaticFieldLeak")
        @Volatile
        var instance: AgoraService? = null

        fun getInstance(context: Context): AgoraService {
            if (instance == null) {
                synchronized(AgoraService::class) {
                    if (instance == null) {
                        instance = AgoraService(context)
                    }
                }
            }
            return instance!!
        }
    }


    private var mHandlerThread: HandlerThread = HandlerThread("RtmService")
    private var mHandler: Handler
    private val mContext: Context = context

    private var timing: ScheduledThreadPoolExecutor? = null
    private lateinit var mRtmClient: RtmClient
    private lateinit var mRtmCallManager: RtmCallManager
    private var mLocalInvitation: LocalInvitation? = null //主叫管理类
    private var mRtmChannel: RtmChannel? = null //频道
    private lateinit var mRemoteInvitation: RemoteInvitation

    private var rtcEngine: RtcEngine? = null
    private var callback: RtcEventChangeListener? = null
    private var remoteAudioStateChangedListener: RemoteAudioStateChangedLister? = null
    private var remoteVideoStateChangedListener: RemoteVideoStateChangedLister? = null

    private var targetChannelId: String? = null
    private var currentJoinedChannelId: String? = null
    private lateinit var currentAccount: String

    private lateinit var mRtcChannelToken: String
    private var mRtcChannelUserId: Int = 0

    private var isCalledEndCallFun: Boolean = false


    /**
     * 标记当前是否在通话中
     */
    private var mVideoStateBusy = AtomicBoolean(false)

    /**
     * 语音通话模式
     */
    private var mCallType = AtomicInteger(CALL_TYPE_VIDEO)

    /**
     * 邀请状态
     */
    @JvmField
    var mInviteState = AtomicBoolean(false)

    /**
     * 记录发送邀请失败测试
     */
    private var inInviteFailedCount = 0

    /**
     * 记录发送邀请失败测试
     */
    private var joinFailedCount: Int = 0
    private var mRtmConnectionState = 0 //记录连接状态
    private var mNeedMuteVideo = false
    private lateinit var mFriendId: String
    private var isIncomingCall: Boolean? = false

    fun setIncomingCall(isIncomingCall: Boolean?) {
        this.isIncomingCall = isIncomingCall
    }

    fun isVoiceCall(): Boolean {
        return mCallType.get() == CALL_TYPE_VOICE
    }


    fun getLastCanceledChannelId(): String? {
        return mLastCanceledChannelId
    }

    private var mLastCanceledChannelId: String? = null

    init {
        mHandlerThread.start()
        mHandler = object : Handler(mHandlerThread.looper) {
            override fun handleMessage(msg: Message) {
                if (msg.what == MSG_LOGOUT && isLoggedIn()) {
                    logout()
                } else if (msg.what == MSG_JOIN_TIMEOUT) {
                    endCall()
                } else if (msg.what == MSG_INCOMING_CALL_NOT_RECEIVE_INVITE) {//音视频来电已登陆RTM但是没有收到邀请
                    resetCallState()
                }
            }
        }
        setupClientManager()
    }

    private fun setupClientManager() {
        try {
            mRtmClient = RtmClient.createInstance(mContext, BuildConfig.VENDORKEY, this)
            mRtmCallManager = mRtmClient.rtmCallManager
            mRtmCallManager.setEventListener(this)
            Log.e("TAG", "RtmClient.getSdkVersion()=" + RtmClient.getSdkVersion())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    @Throws(Exception::class)
    private fun createRtcEngine() {
        rtcEngine =
            RtcEngine.create(mContext, BuildConfig.VENDORKEY, object : IRtcEngineEventHandler() {

                override fun onUserJoined(uid: Int, elapsed: Int) {
                    logger("其他用户加入当前媒体频道回调：uid = $uid, elapsed = $elapsed")
                    setupTime()
                    if (isMainThread()) {
                        mHandler.post { callback?.onUserJoined(uid) }
                    } else {
                        callback?.onUserJoined(uid)
                    }
                }

                override fun onUserOffline(uid: Int, reason: Int) {
                    logger("其他用户离开当前媒体频道回调：uid = $uid, reason = $reason")
                    //endCall()
                }

                override fun onJoinChannelSuccess(channel: String, uid: Int, elapsed: Int) {
                    logger("加入通话频道回调：channel = $channel, uid = $uid, elapsed = $elapsed")
                    if (isValidChannelId(channel)) {
                        setCurrentChannelId(channel)
                        //加入频道后50秒内没有收视频或者音频首帧数据回调，视为加入超时，结束视频通话
                        mHandler.sendEmptyMessageDelayed(
                            MSG_JOIN_TIMEOUT,
                            (50 * 1000).toLong()
                        )
                    }
                }

                override fun onLeaveChannel(stats: RtcStats) {
                    super.onLeaveChannel(stats)
                    logger("离开通话频道回调：通话时长 = " + stats.totalDuration)
                    if (!isCalledEndCallFun) {
                        isCalledEndCallFun = true
                        onCallEnd(stats.totalDuration)
                    }
                }

                override fun onLocalVideoStateChanged(localVideoState: Int, error: Int) {
                    logger("本地视频状态发生改变回调：localVideoState = $localVideoState, error = $error")
                    when (localVideoState) {
                        0 -> {
                            logger("本地视频默认初始状态")
                        }

                        1 -> {
                            logger("本地视频采集设备启动成功")
                        }

                        2 -> {
                            logger("本地视频首帧编码成功")
                        }

                        3 -> {
                            logger("本地视频启动失败")
                        }
                    }
                    if (error != 0) {
                        when (error) {
                            2 -> logger("没有权限启动本地视频采集设备")
                            3 -> logger("本地视频采集设备正在使用中")
                            4 -> logger("本地视频采集失败，建议检查采集设备是否正常工作")
                            5 -> logger("本地视频编码失败")
                            8 -> logger("找不到本地视频采集设备。请检查摄像头是否与设备连接正常")
                            else -> logger("出错原因不明确")
                        }
                        endCall()
                    }
                }

                //新的sdk此方法会回调多次
                override fun onFirstRemoteVideoFrame(
                    uid: Int,
                    width: Int,
                    height: Int,
                    elapsed: Int
                ) {
                    logger("aaaa onFirstRemoteVideoFrame：uid = $uid, width = $width, height = $height, elapsed = $elapsed")
                }

                override fun onFirstRemoteVideoDecoded(
                    uid: Int,
                    width: Int,
                    height: Int,
                    elapsed: Int
                ) {
                    logger("aaaa onFirstRemoteVideoDecoded：uid = $uid, width = $width, height = $height, elapsed = $elapsed")
                    mHandler.removeMessages(MSG_JOIN_TIMEOUT)
                    if (isMainThread()) {
                        mHandler.post { callback?.onFirstRemoteFrame(uid) }
                    } else {
                        callback?.onFirstRemoteFrame(uid)
                    }
                }

                override fun onRemoteAudioStateChanged(
                    uid: Int,
                    state: Int,
                    reason: Int,
                    elapsed: Int
                ) {
                    logger("onRemoteAudioStateChanged：uid = $uid, state = $state,reason:$reason")
                    mHandler.removeMessages(MSG_JOIN_TIMEOUT)
                    when (state) {
                        REMOTE_AUDIO_STATE_STOPPED -> {
                            logger("远端用户停止发送音频流")
                            if (isMainThread()) {
                                mHandler.post { remoteAudioStateChangedListener?.remoteAudioMuted() }
                            } else {
                                remoteAudioStateChangedListener?.remoteAudioMuted()
                            }
                        }

                        REMOTE_AUDIO_STATE_STARTING -> {
                            //setupTime()
                            logger("本地用户已接收远端音频首包")
//                            if (isMainThread()) {
//                                mHandler.post { remoteAudioStateChangedListener?.remoteAudioUnuted() }
//                            } else {
//                                remoteAudioStateChangedListener?.remoteAudioUnuted()
//                            }
                        }

                        REMOTE_AUDIO_STATE_DECODING -> {
                            logger("远端音频流正在解码，正常播放")
                            if (isMainThread()) {
                                mHandler.post { remoteAudioStateChangedListener?.remoteAudioUnuted() }
                            } else {
                                remoteAudioStateChangedListener?.remoteAudioUnuted()
                            }
                        }

                        3 -> logger("远端音频流卡顿")
                        4 -> logger("远端音频流播放失败")
                        5 -> logger("远端用户停止发送音频流")
                        else -> logger("远端音频流默认初始状态")
                    }
                }

                override fun onRemoteVideoStateChanged(
                    uid: Int,
                    state: Int,
                    reason: Int,
                    elapsed: Int
                ) {
                    logger("onRemoteVideoStateChanged：uid = $uid, state = $state,reason:$reason")
                    when (state) {
                        REMOTE_VIDEO_STATE_STOPPED -> {
//                            logger("远端用户停止发送视频流")
//                            if (isMainThread()) {
//                                mHandler.post { remoteVideoStateChangedListener?.remoteVideoMuted() }
//                            } else {
//                                remoteVideoStateChangedListener?.remoteVideoMuted()
//                            }
                        }

                        REMOTE_VIDEO_STATE_STARTING -> {
                            logger("aaaa 本地用户已接收远端视频首包")
                        }

                        2 -> logger("远端视频流正在解码，正常播放")
                        3 -> logger("远端视频流卡顿")
                        4 -> logger("远端视频流播放失败")
                        else -> logger("远端视频默认初始状态")
                    }
                }

                override fun onAudioRouteChanged(routing: Int) {
                    logger("语音路由已变更回调：routing = $routing")
                    when (routing) {
                        0 -> logger("使用耳机为语音路由")
                        1 -> logger("使用听筒为语音路由")
                        2 -> logger("使用不带麦的耳机为语音路由")
                        3 -> logger("使用手机的扬声器为语音路由")
                        4 -> logger("使用外接的扬声器为语音路由")
                        5 -> logger("使用蓝牙耳机为语音路由")
                        else -> logger("使用默认的音频路由")
                    }
                }

                override fun onUserEnableVideo(uid: Int, enabled: Boolean) {
                    logger("onUserEnableVideo远端用户" + uid + (if (enabled) "启用" else "关闭") + "视频功能")
                }

                override fun onWarning(warn: Int) {
                    logger("发生警告回调：warn = $warn")
                    if (isMainThread()) {
                        mHandler.post { callback?.onWarning(warn) }
                    } else {
                        callback?.onWarning(warn)
                    }
                }

                override fun onNetworkQuality(uid: Int, txQuality: Int, rxQuality: Int) {
                    logger("onNetworkQuality:uid=$uid,txQuality=$txQuality,rxQuality=$rxQuality")
                    if (isMainThread()) {
                        mHandler.post { callback?.onNetworkQuality(uid, txQuality, rxQuality) }
                    } else {
                        callback?.onNetworkQuality(uid, txQuality, rxQuality)
                    }
                }

                override fun onError(err: Int) {
                    logger("err:$err")
                    super.onError(err)
                }
            })
        videoConfiguration()
    }

    private fun videoConfiguration() {

        if (BuildConfig.DEBUG) {
            rtcEngine!!.setLogFile("sdcard/Dev/agora-rtc.log")
            rtcEngine!!.setLogFileSize(8 * 1024)
        }

        rtcEngine!!.setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING)
        rtcEngine!!.setClientRole(CLIENT_ROLE_BROADCASTER)
//        rtcEngine!!.setParameters("{\"che.hardware_encoding\":1}")


//        if(BuildConfig.FLAVOR == "Kid_Watch"){
//            rtcEngine?.setCameraCapturerConfiguration(CameraCapturerConfiguration(320,240,CameraCapturerConfiguration.CAMERA_DIRECTION.CAMERA_REAR))
//        }

        val speakerphone = rtcEngine?.setDefaultAudioRoutetoSpeakerphone(true)
        val configuration = rtcEngine?.setVideoEncoderConfiguration(
            VideoEncoderConfiguration(
                VideoEncoderConfiguration.VD_640x480,
                VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_10,
                VideoEncoderConfiguration.STANDARD_BITRATE,
                VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE
            )
        )
        val volume: Int = Utils.getVolume(mContext)
        adjustPlaybackSignalVolume(volume)
        logger("调节录音音量: " + (rtcEngine?.adjustRecordingSignalVolume(200) == 0))
        if (mCallType.get() == CALL_TYPE_VIDEO) {
            var video = rtcEngine?.enableVideo()
            if (video != null && video < 0) {
                video = rtcEngine?.enableVideo()
            }
            logger("configuration:$configuration speakerphone:$speakerphone volume:$volume video:$video")
        } else {
            rtcEngine?.disableVideo()
            rtcEngine?.enableLocalAudio(true)
            logger("当前为语音通话模式")
        }

        //rtcEngine?.setExternalVideoSource(true, true, true)
    }

    fun setChannelToken(channelToken: String) {
        this.mRtcChannelToken = channelToken
    }

    fun setChannelUserId(channelUserId: Int) {
        this.mRtcChannelUserId = channelUserId
    }

    private fun inviteUser(
        channelId: String,
        peer: String,
        channelToken: String,
        channelUserId: Int
    ) {
        mRtcChannelToken = channelToken
        mRtcChannelUserId = channelUserId
        mLocalInvitation = mRtmCallManager.createLocalInvitation(peer)
        mLocalInvitation!!.channelId = channelId
        mRtmCallManager.sendLocalInvitation(mLocalInvitation, object : ResultCallback<Void?> {
            override fun onSuccess(aVoid: Void?) {
                logger("sendLocalInvitation onSuccess()")

//                mHandler.sendMessageDelayed(MSG_INVITE_TIMEOUT, (60 * 1000).toLong())
            }

            override fun onFailure(errorInfo: ErrorInfo) {
                logger("sendLocalInvitation onFailure: $errorInfo")
            }
        })
    }

    @Throws(Exception::class)
    fun getRtcEngine(): RtcEngine? {
        if (rtcEngine == null) {
            createRtcEngine()
        }
        return rtcEngine
    }

    fun adjustPlaybackSignalVolume(volume: Int) {
        logger("调节播放人声的音量: " + (rtcEngine?.adjustPlaybackSignalVolume(volume) == 0))
    }


    @RequiresApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    fun setupRemoteVideo(mRemoteContainer: ViewGroup, uid: Int): Boolean {
        try {
            if (getRtcEngine() != null) {
                val count: Int = mRemoteContainer.childCount
                var view: View? = null
                for (i in 0 until count) {
                    val v: View = mRemoteContainer.getChildAt(i)
                    if (v.tag is Int && v.tag as Int == uid) {
                        view = v
                    }
                }

                if (view != null) {
                    return false
                }

//                if (mRemoteContainer.childCount > 0) {
//                    mRemoteContainer.removeAllViews()
//                }

                val rendererView = RtcEngine.CreateTextureView(mRemoteContainer.context)
                mRemoteContainer.addView(
                    rendererView,
                    ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT
                    )
                )

                val result = getRtcEngine()!!.setupRemoteVideo(
                    VideoCanvas(
                        rendererView,
                        VideoCanvas.RENDER_MODE_HIDDEN,
                        uid
                    )
                )
                rendererView.tag = uid
                return result == 0
            }
        } catch (e: Exception) {
            Log.e("RTM_service", "setupRemoteVideo: ", e)
            e.printStackTrace()
        }
        return false
    }


    fun setupLocalVideo(view: ViewGroup, uid: Int): Boolean {
        try {
            if (getRtcEngine() != null) {
                if (view.childCount > 0) {
                    view.removeAllViews()
                }
                val rendererView = RtcEngine.CreateRendererView(view.context)
                view.addView(
                    rendererView,
                    ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT
                    )
                )
                view.visibility = View.VISIBLE
                return getRtcEngine()!!.setupLocalVideo(
                    VideoCanvas(
                        rendererView,
                        VideoCanvas.RENDER_MODE_HIDDEN,

                        uid
                    )
                ) == 0
            }
        } catch (e: Exception) {
            Log.e("RTM_service", "setupLocalVideo: ", e)
            e.printStackTrace()
        }
        return false
    }


    fun startPreview() {
        rtcEngine?.startPreview()
    }

    fun disableVideo() {
        rtcEngine?.enableLocalVideo(false)
    }

    fun stopPreview() {
        rtcEngine?.stopPreview()
    }

    fun setEventHandler(handler: RtcEventChangeListener?) {
        callback = handler
    }

    fun setRemoteAudioStateChangedListener(listener: RemoteAudioStateChangedLister?) {
        remoteAudioStateChangedListener = listener
    }

    fun setRemoteVideoStateChangedListener(listener: RemoteVideoStateChangedLister?) {
        remoteVideoStateChangedListener = listener
    }

    fun isCallBusy(): Boolean {
        return mInviteState.get() || mVideoStateBusy.get()
    }

    fun resetCallState() {
        mInviteState.set(false)
        mVideoStateBusy.set(false)
    }

    /**
     * 加入信令频道前，记录频道号，用于比较当前加入的频道和回调时的频道号是否相同
     */
    private fun setTargetChannelId(channelId: String?) {
        targetChannelId = channelId
    }

    fun getTargetChannelId(): String? {
        return targetChannelId
    }

    /**
     * 加入通话频道成功后，记录下当前频道号
     */
    private fun setCurrentChannelId(channelId: String?) {
        currentJoinedChannelId = channelId
    }

    /**
     * 发起呼叫，即邀请某用户加入某个频道
     */
    fun inviteCall(
        channelId: String,
        peerAccount: String?,
        channelToken: String,
        channelUserId: Int
    ): Boolean {
        //joinChannel(channelId, channelToken, channelUserId);
        return if (isVideoBusy(false)) {
            inInviteFailedCount = 0
            setTargetChannelId(channelId)
            inviteUser(channelId, peerAccount!!, channelToken, channelUserId)
            logger("开始发送声网邀请")
            true
        } else {
            logger("正在通话中，邀请失败")
            false
        }
    }

    /**
     * 终止向 account 用户发送加入指定频道的邀请
     */
    fun cancelInvite() {
        mRtmCallManager.cancelLocalInvitation(mLocalInvitation, object : ResultCallback<Void?> {
            override fun onSuccess(aVoid: Void?) {
                logger("取消邀请成功")
            }

            override fun onFailure(errorInfo: ErrorInfo) {
                logger("取消邀请失败$errorInfo")
            }
        })
        if (isMainThread()) {
            mHandler.post {
                callback?.onPeerNoResponse()
            }
        } else {
            callback?.onPeerNoResponse()
        }
    }

    /**
     * 接受视频来电呼叫
     * 调用该方法的时机应该在收到信令邀请，唤起来电页面后
     */
    fun acceptInvite(channelId: String): Boolean {
        joinFailedCount = 0
        setTargetChannelId(channelId)
        logger("接受声网视频邀请")
        if (mRemoteInvitation != null) {
            mRtmCallManager.acceptRemoteInvitation(
                mRemoteInvitation,
                object : ResultCallback<Void?> {
                    override fun onSuccess(aVoid: Void?) {
                        logger("接收邀请成功")
                    }

                    override fun onFailure(errorInfo: ErrorInfo) {
                        logger("接收邀请失败：$errorInfo")
                    }
                })
        }
        return joinChannel(channelId, mRtcChannelToken, mRtcChannelUserId)
    }

    /**
     * 拒绝视频来电呼叫
     */
    private fun refusedInvite(remoteInvitation: RemoteInvitation) {
        mRtmCallManager.refuseRemoteInvitation(remoteInvitation, object : ResultCallback<Void?> {
            override fun onSuccess(aVoid: Void?) {
                logger("拒绝接听成功")
            }

            override fun onFailure(errorInfo: ErrorInfo) {
                logger("拒绝接听失败：$errorInfo")
            }
        })
    }

    /**
     * 拒绝视频来电呼叫
     */
    fun refusedInvite() {
        mRtmCallManager.refuseRemoteInvitation(mRemoteInvitation, object : ResultCallback<Void?> {
            override fun onSuccess(aVoid: Void?) {
                logger("拒绝接听成功")
            }

            override fun onFailure(errorInfo: ErrorInfo) {
                logger("拒绝接听失败：$errorInfo")
            }
        })
    }

    fun muteLocalAudioStream(mute: Boolean) {
        rtcEngine?.muteLocalAudioStream(mute)
    }

    fun muteLocalVideoStream(mute: Boolean) {
        rtcEngine?.muteLocalVideoStream(mute)
    }

    fun sendSwitchMsg2Peer() {
        sendPeerMessage(mFriendId, "5000")
    }

    /**
     * 该方法需要在 joinChannel 前调用。如需在加入频道后切换音频路由，请调用 setEnableSpeakerphone
     */
    fun setDefaultAudioRoutetoSpeakerphone(enable: Boolean) {
        rtcEngine?.setDefaultAudioRoutetoSpeakerphone(enable)
    }

    /**
     * 该方法需要在 joinChannel 后调用
     */
    fun setEnableSpeakerphone(enable: Boolean) {
        rtcEngine?.setEnableSpeakerphone(enable)
    }

    private fun channelLeave(channelId: String) {
        if (mRtmChannel != null) {
            mRtmChannel?.leave(object : ResultCallback<Void?> {
                override fun onSuccess(aVoid: Void?) {
                    logger("离开信令频道[$channelId]成功")
                }

                override fun onFailure(errorInfo: ErrorInfo) {
                    logger("离开信令频道[$channelId]失败$errorInfo")
                }
            })
        }

        if (mLocalInvitation != null) {
            mRtmCallManager.cancelLocalInvitation(mLocalInvitation, object : ResultCallback<Void?> {
                override fun onSuccess(aVoid: Void?) {
                    logger("结束呼叫成功")
                }

                override fun onFailure(errorInfo: ErrorInfo) {
                    logger("结束呼叫失败$errorInfo")
                }
            })
        }
    }

    /**
     * 远端接受邀请或者本地接受邀请后调用
     * 加入指定频道。用户一次只能加入一个频道。
     *
     * @return true操作成功，false操作失败
     */
    private fun joinChannel(channelId: String, channelToken: String, channelUserId: Int): Boolean {
        return if (isLoggedIn()) {
            if (!channelId.equals(targetChannelId, ignoreCase = true)) {
                channelLeave(channelId)
            }
            mRtmChannel = mRtmClient.createChannel(channelId, this)
            mRtmChannel?.join(object : ResultCallback<Void?> {
                override fun onSuccess(aVoid: Void?) {
                    logger("加入RTM频道成功：房间号 = $channelId")
                    if (isValidChannelId(channelId)) {
                        var result = -1
                        try {
                            val option = ChannelMediaOptions()
                            option.autoSubscribeAudio = true
                            option.autoSubscribeVideo = true
                            result = getRtcEngine()!!.joinChannel(
                                channelToken,
                                channelId,
                                "Extra Optional Data",
                                channelUserId,
                                option
                            )
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                        when (result) {
                            ERR_OK -> logger("使用token加入媒体频道成功")
                            ERR_INVALID_ARGUMENT -> joinChannelFaied(
                                1,
                                "API 调用了无效的参数",
                                channelToken,
                                channelUserId
                            )

                            ERR_NOT_READY -> joinChannelFaied(
                                1,
                                "检查音频设备状态，检查程序集完整性，尝试重新初始化 SDK",
                                channelToken,
                                channelUserId
                            )

                            else -> joinChannelFaied(
                                1,
                                "加入通信频道失败>>>error code=$result",
                                channelToken,
                                channelUserId
                            )
                        }
                    }
                }

                override fun onFailure(errorInfo: ErrorInfo) {
                    logger("加入[$channelId]信令频道失败$errorInfo")
                    if (isValidChannelId(channelId)) {
                        joinChannelFaied(0, "加入信令频道失败", channelToken, channelUserId)
                    }
                }
            })
            true
        } else {
            logger("请先登录声网，再发送邀请")
            false
        }
    }

    private fun joinChannelFaied(
        ecode: Int,
        errorMsg: String,
        channelToken: String,
        channelUserId: Int
    ) {
        logger("加入频道[$targetChannelId]失败，ecode=$ecode，msg=$errorMsg")
        setCurrentChannelId(null)
        if (++joinFailedCount < 3) {
            joinChannel(targetChannelId!!, channelToken, channelUserId)
        } else {
            endCall()
        }
    }

    /**
     * 电话接通，开始计时
     */
    private fun setupTime() {
        if (timing != null && !timing!!.isShutdown) {
            timing!!.shutdownNow()
        }
        timing = ScheduledThreadPoolExecutor(1,
            object : ThreadFactory {
                private val count = AtomicInteger(0)
                override fun newThread(r: Runnable): Thread {
                    val thread = Thread(r)
                    thread.name = "timer-" + count.addAndGet(1)
                    return thread
                }
            })
        //延时的schedule在shutdown后，不会继续执行没到时间的任务
        // 默认是true，会执行一次正在倒计时的任务再结束
        timing!!.executeExistingDelayedTasksAfterShutdownPolicy = false
        //延时的scheduleAtFixedRate/scheduleWithFixedDelay在shutdown后，不会继续执行没到时间的任务
        // 默认是true，会执行一次正在倒计时的任务再结束
        timing!!.continueExistingPeriodicTasksAfterShutdownPolicy = false
        timing!!.scheduleAtFixedRate(object : TimerTask() {
            var time = 0
            override fun run() {
                time++
                if (isVoiceCall()) {
                    if (BuildConfig.VOICE_COUNTDOWN) {
                        if (time == BuildConfig.VIDEO_CALL_COUNTDOWNTIME) {
                            endCall()
                        }
                        if (isMainThread()) {
                            mHandler.post { callback?.onTiming(BuildConfig.VIDEO_CALL_COUNTDOWNTIME - time) }
                        } else {
                            callback?.onTiming(BuildConfig.VIDEO_CALL_COUNTDOWNTIME - time)
                        }
                    } else {
                        if (isMainThread()) {
                            mHandler.post { callback?.onTiming(time) }
                        } else {
                            callback?.onTiming(time)
                        }
                    }
                } else {
                    if (BuildConfig.VIDEO_COUNTDOWN) {
                        if (time == BuildConfig.VIDEO_CALL_COUNTDOWNTIME) {
                            endCall()
                        }
                        if (isMainThread()) {
                            mHandler.post { callback?.onTiming(BuildConfig.VIDEO_CALL_COUNTDOWNTIME - time) }
                        } else {
                            callback?.onTiming(BuildConfig.VIDEO_CALL_COUNTDOWNTIME - time)
                        }
                    } else {
                        if (isMainThread()) {
                            mHandler.post { callback?.onTiming(time) }
                        } else {
                            callback?.onTiming(time)
                        }
                    }
                }
            }
        }, 1, 1, TimeUnit.SECONDS)
    }

    /**
     * 通话结束调用该方法
     */
    fun endCall() {
        logger("endCall->targetChannelId=${targetChannelId},currentJoinedChannelId=${currentJoinedChannelId}")
        mHandler.removeCallbacksAndMessages(null)
        if (timing != null && !timing!!.isShutdown) {
            timing?.shutdownNow()
        }
        if (targetChannelId != null) {
            channelLeave(targetChannelId!!)
            setTargetChannelId(null)
        }
        if (currentJoinedChannelId != null) {
            rtcEngine?.leaveChannel()
            setCurrentChannelId(null)
        } else {
            onCallEnd(0)
        }
        mVideoStateBusy.set(false)
        mInviteState.set(false)
        logout()
    }

    private fun onCallEnd(totalDuration: Int) {
        mVideoStateBusy.set(false)
        mHandler.post { RtcEngine.destroy() }
        rtcEngine = null
//        setVoiceCall(false)
        if (isMainThread()) {
            mHandler.post {
                callback?.onCallEnd(totalDuration)
            }
        } else {
            callback?.onCallEnd(totalDuration)
        }
        logout()
    }

    fun isLoggedIn(): Boolean {
        return mRtmConnectionState == RtmStatusCode.ConnectionState.CONNECTION_STATE_CONNECTED
    }

    @Synchronized
    fun login(account: String, loginToken: String) {
        if (isLoggedIn()) {
            mRtmClient.logout(object : ResultCallback<Void?> {
                override fun onSuccess(aVoid: Void?) {
                    logger("登出成功")
                    mRtmConnectionState =
                        RtmStatusCode.ConnectionState.CONNECTION_STATE_DISCONNECTED
                }

                override fun onFailure(errorInfo: ErrorInfo) {
                    logger("登出失败，$errorInfo")
                }
            })
        }
        //视频通话结束延迟一分钟退出登录状态，一分钟内再次视频通话，取消延迟退出
        mHandler.removeMessages(0)
        currentAccount = account
        logger("[$currentAccount]开始登录")
        mRtmClient.login(loginToken, currentAccount, this)

    }

    fun isMainThread(): Boolean {
        return Looper.getMainLooper().thread.id == Thread.currentThread().id
    }

    fun logout() {
        if (Thread.currentThread() !== mHandlerThread) {
            mHandler.sendEmptyMessage(MSG_LOGOUT)
            return
        }
        if (isLoggedIn()) {
            if (isMainThread()) {
                mHandler.post {
                    mRtmClient.logout(object : ResultCallback<Void?> {
                        override fun onSuccess(aVoid: Void?) {
                            logger("登出成功")
                            mRtmConnectionState =
                                RtmStatusCode.ConnectionState.CONNECTION_STATE_DISCONNECTED
                            isCalledEndCallFun = false
                        }

                        override fun onFailure(errorInfo: ErrorInfo) {
                            logger("登出失败，$errorInfo")
                        }
                    })
                }
            } else {
                mRtmClient.logout(object : ResultCallback<Void?> {
                    override fun onSuccess(aVoid: Void?) {
                        logger("登出成功")
                        mRtmConnectionState =
                            RtmStatusCode.ConnectionState.CONNECTION_STATE_DISCONNECTED
                        isCalledEndCallFun = false
                    }

                    override fun onFailure(errorInfo: ErrorInfo) {
                        logger("登出失败，$errorInfo")
                    }
                })
            }
        }
    }

    private fun isValidChannelId(channelId: String?): Boolean {
        return (!TextUtils.isEmpty(targetChannelId)
                && targetChannelId.equals(channelId, ignoreCase = true))
    }

    //==============================RtmCallEventListener start====================================
    override fun onLocalInvitationReceivedByPeer(localInvitation: LocalInvitation) {
        //远端已收到呼叫回调，本地将回调 onLocalInvitationReceivedByPeer, 远端回调 onRemoteInvitationReceived。
        logger("远端已收到呼叫回调：Invitation received by " + localInvitation.calleeId)
    }

    override fun onLocalInvitationAccepted(localInvitation: LocalInvitation, response: String?) {
        //远端已接受呼叫回调
        logger("远端已接受呼叫回调：channelID = " + localInvitation.channelId + ", account = " + localInvitation.calleeId + ", state = " + localInvitation.state)
        if (isValidChannelId(localInvitation.channelId)) {
            joinFailedCount = 0
            joinChannel(localInvitation.channelId, mRtcChannelToken, mRtcChannelUserId)
        }
    }

    override fun onLocalInvitationRefused(localInvitation: LocalInvitation, response: String) {
        //接收方调用refuseRemoteInvitation拒绝收到的呼叫, 本地会收到 onLocalInvitationRefused 的回调。
        logger("远端已拒绝呼叫回调：channelID = " + localInvitation.channelId + ", account = " + localInvitation.calleeId + ", state = " + localInvitation.state + ",extra =" + response)
        if (isValidChannelId(localInvitation.channelId)) {
            if (isMainThread()) {
                mHandler.post { callback?.onInviteRefused(response) }
            } else {
                callback?.onInviteRefused(response)
            }
        }
    }

    override fun onLocalInvitationCanceled(localInvitation: LocalInvitation) {
        logger("本地已结束呼叫回调：channelID = " + localInvitation.channelId + ", account = " + localInvitation.calleeId + ", state = " + localInvitation.state)
        if (isValidChannelId(localInvitation.channelId)) {
            if (isMainThread()) {
                mHandler.post { callback?.onInviteEnd() }
            } else {
                callback?.onInviteEnd()
            }
        }
    }

    override fun onLocalInvitationFailure(localInvitation: LocalInvitation, errorCode: Int) {
        logger("呼叫失败回调：channelID = " + localInvitation.channelId + ", account = " + localInvitation.calleeId + ", state = " + localInvitation.state + ", errorCode = " + errorCode)
        if (errorCode == RtmStatusCode.LocalInvitationError.LOCAL_INVITATION_ERR_PEER_NO_RESPONSE
            || errorCode == RtmStatusCode.LocalInvitationError.LOCAL_INVITATION_ERR_PEER_OFFLINE
        ) {
            if (isValidChannelId(localInvitation.channelId)) {
                if (++inInviteFailedCount < 3 && mCallType.get() != CALL_TYPE_PTT) {
                    logger("呼叫失败" + inInviteFailedCount + "次，再次发送邀请")
                    inviteUser(
                        localInvitation.channelId,
                        localInvitation.calleeId,
                        mRtcChannelToken,
                        mRtcChannelUserId
                    )
                } else {
                    logger("呼叫失败" + inInviteFailedCount + "次，结束呼叫")
                    if (mCallType.get() != CALL_TYPE_PTT) {
                        if (isMainThread()) {
                            mHandler.post {
                                callback?.onInviteTimeout()
                            }
                        } else {
                            callback?.onInviteTimeout()
                        }
                        endCall()
                    }
                }
            }
        } else if (errorCode == RtmStatusCode.LocalInvitationError.LOCAL_INVITATION_ERR_INVITATION_EXPIRE) {
            logger("呼叫失败：" + "channelID = " + localInvitation.channelId + ", account = " + localInvitation.calleeId + ", state = " + localInvitation.state + ", errorCode = " + errorCode)
            if (isValidChannelId(localInvitation.channelId)) {
                if (isMainThread()) {
                    mHandler.post {
                        callback?.onInviteTimeout()
                    }
                } else {
                    callback?.onInviteTimeout()
                }
                endCall()
            }
        }
    }

    override fun onRemoteInvitationReceived(remoteInvitation: RemoteInvitation) {
        logger("收到邀请：" + "channelID = " + remoteInvitation.channelId + ", account = " + remoteInvitation.callerId + ", state = " + remoteInvitation.state + ", response=" + remoteInvitation.response)

        if (isIncomingCall!!) {
            mHandler.removeMessages(MSG_INCOMING_CALL_NOT_RECEIVE_INVITE)
        }
        if (DataProvider.inForbidPeriodNow()) {
            logger("处于上课模式，拒绝接听")
            mRemoteInvitation = remoteInvitation
            mFriendId = remoteInvitation.callerId
            refusedInvite()
        } else if (!Utils.isPhoneIdle(mContext)) {
            logger("当前正在语音通话中，拒绝接听")
            mRemoteInvitation = remoteInvitation
            mFriendId = remoteInvitation.callerId
            mRemoteInvitation.response = RESPONSE_BUSY
            refusedInvite()
        } else if (mVideoStateBusy.get()) {
            remoteInvitation.response = RESPONSE_BUSY
            logger("当前正在视频通话中，拒绝接听")
            refusedInvite(remoteInvitation)
        } else if (isVideoBusy(false)) {
            mRemoteInvitation = remoteInvitation
            mFriendId = remoteInvitation.callerId
            //亮屏
            val mPowerManager: PowerManager =
                mContext.getSystemService(Context.POWER_SERVICE) as PowerManager
            val mWakeLock = mPowerManager.newWakeLock(
                PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.SCREEN_DIM_WAKE_LOCK,
                "My:Tag"
            )
            mWakeLock.acquire()

            mInviteState.set(false)
            setTargetChannelId(remoteInvitation.channelId)
            var uri = ""
            var action = ""
            val callType = mCallType.get()
            logger("callType-->$callType")
            when (callType) {
                CALL_TYPE_VIDEO -> {
                    uri = InternalConstants.INCOMING_VIDEO_CALL
                    action = InternalConstants.ACTION_INCOMING_VIDEO_CALL
                }

                CALL_TYPE_VOICE -> {
                    uri = InternalConstants.INCOMING_VOICE_CALL
                    action = InternalConstants.ACTION_INCOMING_VIDEO_CALL
                }

                CALL_TYPE_PTT -> {
                    uri = InternalConstants.INCOMING_PTT_CALL
                    action = InternalConstants.ACTION_PTT_CALL
                }
            }
            uri += "?" + InternalConstants.CALL_QUERY_PARA_FOLLOWER_ID + "=" + mFriendId + "&" + InternalConstants.CALL_QUERY_PARA_CHANNEL + "=" + remoteInvitation.channelId
            val intent = Intent(action, Uri.parse(uri))
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            mContext.startActivity(intent)

            mWakeLock?.release()
        }
    }

    fun isVideoBusy(b: Boolean): Boolean {
        return mVideoStateBusy.compareAndSet(b, true)
    }

    override fun onRemoteInvitationAccepted(remoteInvitation: RemoteInvitation?) {}

    override fun onRemoteInvitationRefused(remoteInvitation: RemoteInvitation?) {}

    override fun onRemoteInvitationCanceled(remoteInvitation: RemoteInvitation) {
        resetCallState()
        mLastCanceledChannelId = remoteInvitation.channelId
        logger("对方已结束呼叫回调：channelID = " + remoteInvitation.channelId + ", account = " + remoteInvitation.callerId + ", state = " + remoteInvitation.state)
        val validChannelId = isValidChannelId(remoteInvitation.channelId)
        if (validChannelId) {
            if (isMainThread()) {
                mHandler.post { callback?.onInviteEnd() }
            } else {
                callback?.onInviteEnd()
            }
        }
    }

    override fun onRemoteInvitationFailure(remoteInvitation: RemoteInvitation?, errorCode: Int) {
        logger("onRemoteInvitationFailure：channelID = " + remoteInvitation!!.channelId + ", account = " + remoteInvitation.callerId + ", state = " + remoteInvitation.state + ", errorCode = " + errorCode)
        val validChannelId = isValidChannelId(remoteInvitation.channelId)
        if (validChannelId) {
            if (callback != null) {
                if (isMainThread()) {
                    mHandler.post { callback!!.onInviteEnd() }
                } else {
                    callback!!.onInviteEnd()
                }
            } else {
                endCall()
            }
        }
    }
    //==============================RtmCallEventListener end====================================


    //==============================RtmClientListener start====================================


    //==============================RtmCallEventListener end====================================
    //==============================RtmClientListener start====================================
    override fun onConnectionStateChanged(state: Int, reason: Int) {
        when (state) {
            RtmStatusCode.ConnectionState.CONNECTION_STATE_ABORTED -> {
                logger("SDK停止登录Agora RTM系统。可能原因：另一实例已经以同一用户ID登录Agora RTM系统")
            }

            RtmStatusCode.ConnectionState.CONNECTION_STATE_CONNECTED -> {
                logger("SDK 已登录 Agora RTM 系统")
            }

            RtmStatusCode.ConnectionState.CONNECTION_STATE_CONNECTING -> {
                logger("SDK 正在登录 Agora RTM 系统")
            }

            RtmStatusCode.ConnectionState.CONNECTION_STATE_DISCONNECTED -> {
                logger("初始状态。SDK 未连接到 Agora RTM 系统。")
            }

            RtmStatusCode.ConnectionState.CONNECTION_STATE_RECONNECTING -> {
                logger("SDK 与 Agora RTM 系统连接由于网络原因出现中断，SDK 正在尝试自动重连 Agora RTM 系统。")
            }
        }
        mHandler.post {
            try {
                if (BuildConfig.DEBUG) {
                    showToast(if (state < stateArr.size) stateArr[state] + state else stateArr[0] + state)
                }
            } catch (e: Exception) {
                Log.v("rtmservice", "onConnectionStateChanged: ", e)
            }
        }
        mRtmConnectionState = state
    }

    private fun showToast(s: String) {
        Toast.makeText(mContext, s, Toast.LENGTH_LONG).show()

    }

    var stateArr = arrayOf(
        "连接发生改变 ", "未连接系统 ", "正在登陆 ", "登陆成功 ", "重连系统 ", "被踢下线 "
    )

    override fun onMessageReceived(rtmMessage: RtmMessage, peerId: String) {
        logger("收到频道消息,rtmMessage=" + rtmMessage.text + ",peerId = " + peerId)
        val state = rtmMessage.text.toInt()
        if (state == 1000) { //邀请切换为视频
            if (isMainThread()) {
                mHandler.post { callback?.switch2VideoMode(0) }
            } else {
                callback?.switch2VideoMode(0)
            }
        } else if (state == 2000) { //对方已同意切换为视频模式
            rtcEngine!!.enableVideo()
            if (isMainThread()) {
                mHandler.post { callback?.switch2VideoMode(1) }
            } else {
                callback?.switch2VideoMode(1)
            }
        } else if (state == 3000) { //对方拒绝切换为视频模式
            if (isMainThread()) {
                mHandler.post { callback?.switch2VideoMode(2) }
            } else {
                callback?.switch2VideoMode(2)
            }
        } else if (state == 5000) { //对方从视频切换到音频
            if (isMainThread()) {
                mHandler.post { remoteVideoStateChangedListener?.remoteVideoMuted() }
            } else {
                remoteVideoStateChangedListener?.remoteVideoMuted()
            }
        }
    }

    override fun onImageMessageReceivedFromPeer(rtmImageMessage: RtmImageMessage?, s: String?) {}

    override fun onFileMessageReceivedFromPeer(rtmFileMessage: RtmFileMessage?, s: String?) {}

    override fun onMediaUploadingProgress(
        rtmMediaOperationProgress: RtmMediaOperationProgress?,
        l: Long
    ) {
    }

    override fun onMediaDownloadingProgress(
        rtmMediaOperationProgress: RtmMediaOperationProgress?,
        l: Long
    ) {
    }

    override fun onTokenExpired() {}

    override fun onPeersOnlineStatusChanged(map: Map<String?, Int?>) {
        logger("onPeersOnlineStatusChanged: " + map.size)
    }
    //==============================RtmClientListener end====================================

    //==============================RtmClientListener end====================================
    /**
     * 登录成功回调
     */
    override fun onSuccess(responseInfo: Void?) {
        logger("login onSuccess")
        mRtmConnectionState = RtmStatusCode.ConnectionState.CONNECTION_STATE_CONNECTED
        mInviteState.set(true)
        callback?.onLoggedIn()
        if (isIncomingCall!!) {
            mHandler.sendEmptyMessageDelayed(MSG_INCOMING_CALL_NOT_RECEIVE_INVITE, 30000)
        }
    }

    /**
     * 登录失败回调
     */
    override fun onFailure(errorInfo: ErrorInfo) {
        logger("login onFailure：errorInfo = $errorInfo")
        mInviteState.set(false)
        mRtmConnectionState = RtmStatusCode.ConnectionState.CONNECTION_STATE_DISCONNECTED
    }


    //==============================RtmChannelListener start====================================
    override fun onMemberCountUpdated(memberCount: Int) {
        logger("频道成员数量改变，当前频道成员人数：$memberCount")
    }

    override fun onAttributesUpdated(list: List<RtmChannelAttribute?>?) {
        logger("频道属性更新回调")
    }

    override fun onMessageReceived(rtmMessage: RtmMessage, rtmChannelMember: RtmChannelMember) {
        logger("收到频道消息,rtmMessage=" + rtmMessage.text + ",UserId = " + rtmChannelMember.userId)
    }

    override fun onImageMessageReceived(
        rtmImageMessage: RtmImageMessage?,
        rtmChannelMember: RtmChannelMember?
    ) {
    }

    override fun onFileMessageReceived(
        rtmFileMessage: RtmFileMessage?,
        rtmChannelMember: RtmChannelMember?
    ) {
    }

    override fun onMemberJoined(rtmChannelMember: RtmChannelMember) {
        logger("信令频道内有用户加入：account = " + rtmChannelMember.userId)
    }

    override fun onMemberLeft(rtmChannelMember: RtmChannelMember) {
        logger("信令频道内有用户离开：account = " + rtmChannelMember.userId)
        if (rtmChannelMember.userId == mFriendId) {
            endCall()
        }
    }

    fun muteRemoteVideoEnable(enable: Boolean) {
        if (!enable && mNeedMuteVideo) {
            rtcEngine!!.muteAllRemoteVideoStreams(enable)
            mNeedMuteVideo = true
        }
    }

    fun setFriendId(friendId: String) {
        mFriendId = friendId
    }

    @Synchronized
    fun setCallType(callType: Int) {
        logger("setCallType value=" + callType)
        mCallType.set(callType)
    }

    fun switch2Video() {
        sendPeerMessage(mFriendId, "1000") //发消息邀请切换视频
    }


    fun muteRemoteVideoStream(uid: Int, mute: Boolean) {
        rtcEngine!!.muteRemoteVideoStream(uid, mute) //订阅
    }


    fun acceptSwitch2Video() {
        rtcEngine!!.enableVideo() //开启视频
        sendPeerMessage(mFriendId, "2000")
    }

    fun refuseSwitch2Video() {
        sendPeerMessage(mFriendId, "3000")
    }

    fun switchCamera() {
        if (rtcEngine != null) {
            val switchResult = rtcEngine!!.switchCamera()
            logger("切换摄像头 " + if (switchResult == 0) "成功" else "失败")
        }
    }


    private fun logger(text: String) {
        if (BuildConfig.DEBUG) {
            Log.i("AgoraService", Thread.currentThread().stackTrace[4].toString() + ">>>" + text)
        }
    }

    interface RemoteAudioStateChangedLister {
        fun remoteAudioMuted()
        fun remoteAudioUnuted()
    }

    interface RemoteVideoStateChangedLister {
        fun remoteVideoMuted()
    }


    interface RtcEventChangeListener {
        /**
         * 登录信令成功回调
         */
        fun onLoggedIn()

        /**
         * 对方拒绝邀请回调
         *
         * @param response
         */
        fun onInviteRefused(response: String?)

        /**
         * 对方加入频道回调，这个时候设置远端图像
         */
        fun onUserJoined(uid: Int)

        /**
         * 已收到远端首帧数据，这时候可以开始计时了
         */
        fun onFirstRemoteFrame(uid: Int)

        /**
         * 视频通话计时
         */
        fun onTiming(secs: Int)

        /**
         * 结束呼叫回调
         * 呼叫到达后才会走该回调方法
         * 比如：
         * 1.发送呼叫邀请，对方已收到邀请，本地调用[RtmService.cancelInvite] 结束呼叫
         * 2.收到呼叫邀请，对方调用[RtmService.cancelInvite] 结束呼叫
         */
        fun onInviteEnd()

        /**
         * 通话结束回调
         */
        fun onCallEnd(totalDuration: Int)

        /**
         *
         */
        fun onWarning(warn: Int)

        fun switch2VideoMode(mode: Int)


        fun onNetworkQuality(uid: Int, txQuality: Int, rxQuality: Int)

        //从对方接收到邀请开始计算，1分钟内无应答
        fun onPeerNoResponse()


        //连续呼叫3次为失败则为呼叫超时
        fun onInviteTimeout()
    }


    abstract class IncomingCallEventHandler : RtcEventChangeListener {
        override fun onLoggedIn() {}
        override fun onInviteRefused(response: String?) {}
    }


    private fun sendPeerMessage(peerId: String, content: String) {
        val message = mRtmClient.createMessage()
        message.text = content
        val option = SendMessageOptions()
        option.enableOfflineMessaging = false
        mRtmClient.sendMessageToPeer(peerId, message, option, object : ResultCallback<Void?> {
            override fun onSuccess(aVoid: Void?) {}
            override fun onFailure(errorInfo: ErrorInfo) {}
        })
    }
}